﻿using JWT.Algorithms;
using JWT.Serializers;
using JWT;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TiTi.tea.Comm
{
    public class JwtHelper
    {
        /// <summary>
        /// jwt私钥
        /// </summary>
        private const string SecretKey = "GGGK.Bookstore-03a04ff4f8e21-1e1428c9-2424-4a85-91e5-73d52feb5fdf";

        /// <summary>
        /// 创建新token
        /// </summary>
        /// <param name="payload"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">payload 为 null。</exception>
        public static string GenerateToken(AuthInfo payload)
        {
            if (payload == null)
                throw new ArgumentNullException(nameof(payload));

            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密算法
            IJsonSerializer serializer = new JsonNetSerializer();//序列化
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//加密器

            var token = encoder.Encode(payload, SecretKey);//加密
            return token;
        }

        /// <summary>
        /// 解码token
        /// </summary>
        /// <param name="strToken">token字符串</param>
        /// <returns>json内容</returns>
        /// <exception cref="ArgumentNullException">strToken 为 null、空和由空白字符组成。</exception>
        public static AuthInfo GetDecodingToken(string strToken, bool isCheckexpire = true)
        {
            if (string.IsNullOrWhiteSpace(strToken))
                throw new ArgumentNullException(nameof(strToken));

            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IDateTimeProvider provider = new UtcDateTimeProvider();
            IJwtValidator validator = new JwtValidator(serializer, provider);
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);

            var auth = decoder.Decode(strToken, SecretKey, true).FormJsonTo<AuthInfo>();

            //需要验证是否过期
            if (isCheckexpire)
            {
                var exp = auth.exp;
                var diff = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
                if (diff > exp)
                {
                    return null;
                }
            }
            return auth;
        }


    }

    public class TokenInfo
    {
        public TokenInfo()
        {
            iss = "GGGK.com";
            iat = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
            exp = iat + 188800;
            aud = "";
            sub = "GGGK.com";
            jti = "GGGK.com." + DateTime.Now.ToString("yyyyMMddhhmmssfff");
        }

        /// <summary>
        /// jwt签发者
        /// </summary>
        public string iss { get; set; }
        /// <summary>
        /// jwt的签发时间
        /// </summary>
        public double iat { get; set; }
        /// <summary>
        /// jwt的过期时间，这个过期时间必须要大于签发时间
        /// </summary>
        public double exp { get; set; }
        /// <summary>
        /// 接收jwt的一方
        /// </summary>
        public string aud { get; set; }
        /// <summary>
        /// 定义在什么时间之前，该jwt都是不可用的
        /// </summary>
        public double nbf { get; set; }
        /// <summary>
        /// jwt所面向的用户
        /// </summary>
        public string sub { get; set; }
        /// <summary>
        /// jwt的唯一身份标识，主要用来作为一次性token，从而回避重放攻击
        /// </summary>
        public string jti { get; set; }
    }

    public class AuthInfo : TokenInfo
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Roles { get; set; }
        public string Token { get; set; }
        public long Exp { get; set; }
    }
}

